package com.ai.util;

import com.serotonin.modbus4j.ModbusFactory;
import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.exception.ErrorResponseException;
import com.serotonin.modbus4j.exception.ModbusInitException;
import com.serotonin.modbus4j.exception.ModbusTransportException;
import com.serotonin.modbus4j.ip.IpParameters;
import com.serotonin.modbus4j.locator.BaseLocator;

import java.util.Objects;

/**
 * @Author jiaok
 * @Date 2024-11-25 14:01
 */
public class Modbus4jUtils {


    static ModbusFactory modbusFactory;

    static {
        if (modbusFactory == null) {
            modbusFactory = new ModbusFactory();
        }
    }


    public static void main(String[] args) {
        try {
            ModbusMaster master = getMaster("127.0.0.1", 502);
            if (Objects.isNull(master)){
                System.out.println("modbus连接失败");
            }
        } catch (ModbusInitException e) {
            System.out.println("modbus连接失败");
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取modbusTcp的客户端连接
     * @param host ip
     * @param port 端口 默认为502
     * @return 创建modbus-tcp通信客户端连接
     * @throws ModbusInitException 创建失败
     */
    public static ModbusMaster getMaster(String host,Integer port) throws ModbusInitException {

        IpParameters ipParameters = new IpParameters();
        ipParameters.setHost(host);
        ipParameters.setPort(port);

        //创建modbus-tcp通信客户端连接
        ModbusMaster tcpMaster = modbusFactory.createTcpMaster(ipParameters, true);
        tcpMaster.init();

        return tcpMaster;
    }


    /**
     * 读取指定寄存器存储的值
     * @param slaveId  从机id
     * @param offset 偏移量，默认从40001开始， （若读取40003，则需设为40003-40001=2）
     * @param dataType 存储值的数据类型
     * @return 值
     * @throws ModbusTransportException
     * @throws ErrorResponseException
     * @throws ModbusInitException
     */
    public static Number readHoldingRegister(int slaveId, int offset, int dataType)
            throws ModbusTransportException, ErrorResponseException, ModbusInitException {
        // 03 Holding Register类型数据读取
        BaseLocator<Number> loc = BaseLocator.holdingRegister(slaveId, offset, dataType);
        Number value = getMaster("1.2.3.4",502).getValue(loc);
        return value;
    }



}
